home *** CD-ROM | disk | FTP | other *** search
- {
- JD3GTRCW.TRANSCOM@transcom.safb.af.mil (CONROY WILLIAM F)
-
- I have seen numerous requests for XMS routines. Here are some I have
- written for a programming effort I headed.
- Feel free to use in any way fit.
- }
-
- {$O+,F+}
- UNIT XMSUnit;
- { Programmer: Major William F. Conroy III }
- { Last Mod: 3/12/93 }
- { Touched: File date set to coorespond to baseline date }
- { for Computer Aided Aircrew Scheduling System }
- { }
- { This unit is written to give access to the XMS memory Specification for }
- { the IBM PC. Do not alter this unit without an excellent understanding }
- { of the PC internal architecture, the Extended Memory Specification(XMS) }
- { and the Borland Inline Assembler. For a much more in depth discussion }
- { of the XMS memory standard and how to implement it on a PC class
- computer }
- { Refer to "Extending Dos" by Ray Duncan, Published by Addison Wesley }
-
- INTERFACE
-
- TYPE
- PHandlePtrArray = ^THandlePtrArray;
- THandlePtrArray = ARRAY [1..10]OF WORD;
- { This type definition is used by the graphics system as a way }
- { to dynamically allocate space to hold the handles required to }
- { access the extended memory. }
-
- PXMSParamBlock = ^TXMSParamBlock;
- TXMSParamBlock = RECORD
- LengthOfBlock : LONGINT; { Size of block to move }
- SourceEMBHandle : WORD;
- { 0 if source is in conventional memory, }
- { handle returned by AllocateEMB otherwise }
- SourceOffset : LONGINT;
- { if SourceEMBHandle= 0 SourceOffset contains }
- { a far pointer in Intel standard format else }
- { SourceOffset indicates offset from the base }
- { of the block. }
- DestEMBHandle : WORD;
- { 0 if source is in conventional memory, }
- { handle returned by AllocateEMB otherwise }
- DestOffset : LONGINT;
- { if DestEMBHandle= 0 DestOffset contains }
- { a far pointer in Intel standard format else }
- { DestOffset indicates offset from the base }
- { of the block. }
- END;
- { This type definition is used by the XMM memory manager for }
- { block memory moves. As required by the xms specification. }
-
- VAR
- XMSExists : BOOLEAN;
-
- { Function AllocateEMB allocates an Extended Memory Block in Extended }
- { memory. It requests the block via the Extended Memory Manager(XMM) }
- { It returns True if it was successful False otherwise. If true, if }
- { EMB_Handle will contain the Extended Memory Block Handle. If }
- {returning false, the errorcode is in the ErrorCode parameter. }
- FUNCTION AllocateEMB(VAR EMB_Handle, ParRequested, ErrorCode : WORD) : BOOLEAN;
-
- { Function FreeEMB releases an Extended Memory Block in Extended Memory }
- { allocated by the AllocateEMB function call. It requests the XMM }
- { remove the block. It returns True if it was successful False }
- { otherwise. If true, if block was released correctly. If returning }
- { false, the errorcode is in the ErrorCode parameter. }
- FUNCTION FreeEMB(VAR EMB_Handle, ErrorCode : WORD) : BOOLEAN;
-
- { Function MoveEMB allows memory tranfers between conventional and XMS }
- { Memory. This function requires a filled in TXMSParamBlock record. }
- { It returns True if it was successful False otherwise. If true, the }
- { memory block was successfully moved. If returning false, the }
- { errorcode is in the ErrorCode parameter. }
- FUNCTION MoveEMB(PParamBlock : PXMSParamBlock; VAR ErrorCode : WORD) : BOOLEAN;
-
-
-
- IMPLEMENTATION
-
- VAR
- XMMAddress : POINTER;
- XMS_Version : WORD;
- XMM_DriverVersion : WORD;
- HMA_Exists : BOOLEAN;
- LastErrorCode : WORD;
-
-
- {---------------------------------------------------------------------------}
- { }
- { Local Procedure }
- { function XMSPresent }
- { }
- { This function return true if there is an Extended memory manager present }
- { in the system capable of supporting our XMS requests. It uses a DOS }
- { multiplexing interrupt request to determine if the driver signiture is }
- { present in the system. This is the Microsoft recomended method of }
- { determining the presence of this driver. }
- { }
- {---------------------------------------------------------------------------}
-
- FUNCTION XMSPresent : BOOLEAN; ASSEMBLER;
-
- ASM
- MOV AX, 4300h { MultiPlexing interrupt request number }
- INT 2fh { Dos Multiplexing Interrupt }
- CMP AL, 80h { was the signature byte returned in AL }
- JZ @1 { yes?, jump to @1 }
- MOV AX, 00h { set false for return }
- JMP @2 { unconditional jump to end of function }
- @1:
- MOV AX, 01h { set True for return then fall thru to }
- { exit. }
- @2:
- END;
-
- {------------------------------------------------------------------------- --}
- { }
- { Local Procedure }
- { function ReturnDriverAddress }
- { }
- { This function return true if it could determine the device driver entry }
- { point. This information is required to call any XMS functions. It uses }
- { a DOS multiplexing interrupt request to get this address. This is the }
- { Microsoft recomended method of getting the base address of this driver. }
- { This address is required to setup an indirect call to the driver by the }
- { XMS functions. }
- { }
- {---------------------------------------------------------------------------}
- FUNCTION ReturnDriverAddress : POINTER; ASSEMBLER;
- { This function returns the address for the XMM memory manager }
- { This value is required to later call the driver for XMS calls }
-
- ASM
- MOV AX, 4310h { MultiPlexing interrupt request number }
- INT 2fh { Dos Multiplexing Interrupt }
- { Set Registers up for Return of Pointer }
- MOV AX, BX { Set Offset Value }
- MOV DX, ES { Set Segment Value }
- END;
-
- {-------------------------------------------------------------------------}
- { }
- { Local Procedure }
- { function GetXMSVersion }
- { }
- {-------------------------------------------------------------------------}
- FUNCTION GetXMSVersion(VAR XMS_Version, XMM_DriverVersion : WORD;
- VAR HMA_Exists : BOOLEAN;
- VAR ErrorCode : WORD) : BOOLEAN; ASSEMBLER;
-
- { This function loads the version numbers into the unit global }
- { variables. The information is coded in binary Coded Decimal. }
-
- ASM
- XOR AX, AX { set ax to zero }
- CALL XMMAddress { indirect call to XMM driver }
- CMP AX, 00h { error set ? }
- JZ @1 { Jump error finish }
-
- LES DI, XMS_Version { Load XMS_Version Address into es:di }
- MOV ES:[DI],AX { Load variable indirect }
-
- LES DI, XMM_DriverVersion { Load XMM_DriverVrsn Address in es:di }
- MOV ES:[DI],BX { Load variable Indirect }
-
- LES DI, HMA_Exists { Load HMA_Exists Address in es:di }
- MOV ES:[DI],DX { Load variable Indirect }
-
- LES DI,ErrorCode { Load ErrorCode Address into es:di }
- MOV WORD PTR ES:[DI],00h { Clear Error Code }
- MOV AX, 01h { set function return to true }
- JMP @2 { Jump to finish }
-
- @1:
- LES DI, ErrorCode { Load error code address in es:di }
- MOV WORD PTR ES:[DI],00h { copy 0 into ErrorCode }
- @2:
- END;
-
- {-------------------------------------------------------------------------}
- { }
- { Exported Procedure }
- { function AllocateEMB }
- { }
- { }
- { Function AllocateEMB allocates an Extended Memory Block in Extended }
- { memory. It requests the block via the Extended Memory Manager(XMM) }
- { It returns True if it was successful False otherwise. If true, if }
- { EMB_Handle will contain the Extended Memory Block Handle. If }
- { returning false, the errorcode is in the ErrorCode parameter. }
- { }
- {-------------------------------------------------------------------------}
- FUNCTION AllocateEMB(VAR EMB_Handle, ParRequested,
- ErrorCode : WORD) : BOOLEAN; ASSEMBLER;
-
- ASM
- MOV AH, 09h { set ax for Allocate EMB call }
- LES DI, ParRequested { load ParRequested address in es:di }
- MOV DX, ES:[DI] { copy parRequested value in DX }
- CALL XMMAddress { indirect call to XMM driver }
- CMP AX, 00h { error set ? }
- JZ @1 { Jump error finish }
- LES DI, EMB_Handle { load EMB_Handle in es:di }
- MOV ES:[DI],DX { copy DX into EMB_Handle }
- MOV AX, 01h { Return True }
- LES DI, ErrorCode { Load error code address in es:di }
- MOV WORD PTR ES:[DI],00h { copy 0 into ErrorCode }
- JMP @2 { unconditional jump to finish }
- { Error Finish }
- @1:
- LES DI, ErrorCode { load ErrorCode in es:di }
- MOV BYTE PTR ES:[DI],BL { copy BL into ErrorCode }
- @2:
- END;
-
- {-------------------------------------------------------------------------}
- { }
- { Exported Procedure }
- { function FreeEMB }
- { }
- { Function FreeEMB releases an Extended Memory Block in Extended Memory }
- { allocated by the AllocateEMB function call. It requests the XMM }
- { remove the block. It returns True if it was successful False }
- { otherwise. If true, if block was released correctly. If returning }
- { false, the errorcode is in the ErrorCode parameter. }
- { }
- {-------------------------------------------------------------------------}
- FUNCTION FreeEMB(VAR EMB_Handle, ErrorCode : WORD) : BOOLEAN; ASSEMBLER;
-
- ASM
- XOR AX, AX { clear AX to zero }
- MOV AH, 0Ah { set ax for Free EMB call }
- LES DI, EMB_Handle { load EMB_Handle address in es:di }
- MOV DX, ES:[DI] { load EMB_Handle value in DX }
- CALL XMMAddress { indirect call to XMM driver }
- CMP AX, 00h { error set ? }
- JZ @1 { Jump error finish }
- MOV AX, 01H { Set True }
- LES DI, ErrorCode { Load error code address in es:di }
- MOV WORD PTR ES:[DI],00h { copy 0 into ErrorCode }
- JMP @2 { unconditional jump to finish }
- { Error Finish }
- @1:
- LES DI, ErrorCode { load ErrorCode in es:di }
- MOV BYTE PTR ES:[DI],BL { copy BL into ErrorCode }
- @2:
- END;
-
- {-------------------------------------------------------------------------}
- { }
- { Exported Procedure }
- { function MoveEMB }
- { }
- { Function MoveEMB allows memory tranfers between conventional and XMS }
- { Memory. This function requires a filled in TXMSParamBlock record. }
- { It returns True if it was successful False otherwise. If true, the }
- { memory block was successfully moved. If returning false, the }
- { errorcode is in the ErrorCode parameter. }
- { }
- {-------------------------------------------------------------------------}
- FUNCTION MoveEMB(PParamBlock : PXMSParamBlock;
- VAR ErrorCode : WORD) : BOOLEAN; ASSEMBLER;
-
- ASM
- MOV AX, DS { move DS to AX register }
- MOV ES, AX { move AX to ES register }
- MOV AH, 0Bh { set ax for Move EMB call }
- PUSH DS { push DS to Stack }
- LDS SI, PParamBlock { load PParamBlock Address to ds:si }
- MOV DI, OFFSET XMMAddress { move XMMAddress offset to di }
- CALL DWORD PTR ES:[DI] { indirect call to XMMdriver via es:di }
- POP DS { save TP's data segment }
- CMP AX, 00h { error set ? }
- JZ @1 { Jump error finish }
- MOV AX, 01H { Set True }
- LES DI, ErrorCode { Load error code address in es:di }
- MOV WORD PTR ES:[DI],00h { copy 0 into ErrorCode }
- JMP @2 { unconditional jump to finish }
- { Error Finish }
- @1:
- LES DI, ErrorCode { load ErrorCode in es:di }
- MOV WORD PTR ES:[DI],AX { Clear ErrorCode prior to load }
- MOV BYTE PTR ES:[DI],BL { copy BL into ErrorCode }
- MOV AX, 01h { Return False }
- @2:
- END;
-
- BEGIN
- XMSExists := XMSPresent;
- IF XMSExists THEN
- BEGIN
- XMMAddress := ReturnDriverAddress;
- GetXMSVersion(XMS_Version, XMM_DriverVersion, HMA_Exists, LastErrorCode);
- END;
- END.